home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / text / hyper / hsc_source.lha / hsc / source / hsclib / defattr.c < prev    next >
C/C++ Source or Header  |  1996-10-14  |  13KB  |  498 lines

  1. /*
  2.  * hsclib/defattr.c
  3.  *
  4.  * functions to define new attribute
  5.  * and manipulate attribute lists
  6.  *
  7.  * Copyright (C) 1995,96  Thomas Aglassinger
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  *
  23.  * updated: 13-Oct-1996
  24.  * created:  6-Jan-1995
  25.  */
  26.  
  27. #define NOEXTERN_HSCLIB_DEFATTR
  28.  
  29. #include "hsclib/inc_base.h"
  30.  
  31. #include "hsclib/defattr.h"
  32. #include "hsclib/eval.h"
  33. #include "hsclib/input.h"
  34.  
  35. /*
  36.  *-------------------------------------
  37.  * misc. functions
  38.  *-------------------------------------
  39.  */
  40. static BYTE str2vartype(STRPTR s)
  41. {
  42.     BYTE vartype = VT_NONE;
  43.  
  44.     if (!upstrcmp(VT_STR_URI, s))
  45.         vartype = VT_URI;
  46.     else if (!upstrcmp(VT_STR_STRING, s))
  47.         vartype = VT_STRING;
  48.     else if (!upstrcmp(VT_STR_BOOL, s))
  49.         vartype = VT_BOOL;
  50.     else if (!upstrcmp(VT_STR_NUM, s))
  51.         vartype = VT_NUM;
  52.     else if (!upstrcmp(VT_STR_ENUM, s))
  53.         vartype = VT_ENUM;
  54.     else if (!upstrcmp(VT_STR_ID, s))
  55.         vartype = VT_ID;
  56.     else if (!upstrcmp(VT_STR_COLOR, s))
  57.         vartype = VT_COLOR;
  58.  
  59.     return (vartype);
  60. }
  61.  
  62. /*
  63.  * check_varlist: check for required attributes missing
  64.  *
  65.  * result: TRUE, if all attributes ok
  66.  */
  67. static BOOL check_reqvar(HSCPRC * hp, HSCATTR * var)
  68. {
  69.     BOOL ok = TRUE;
  70.  
  71.     if ((var->varflag & VF_REQUIRED)
  72.         && (!var->text))
  73.     {
  74.         hsc_message(hp, MSG_MISS_REQ_ATTR,
  75.                     "required %A missing", var);
  76.         ok = FALSE;
  77.     }
  78.  
  79.     return (ok);
  80. }
  81.  
  82. BOOL check_varlist(HSCPRC * hp, DLLIST * varlist)
  83. {
  84.     DLNODE *nd = varlist->first;
  85.     BOOL ok = TRUE;
  86.  
  87.     while (nd)
  88.     {
  89.         ok &= check_reqvar(hp, (HSCATTR *) (nd->data));
  90.         nd = nd->next;
  91.     }
  92.  
  93.     return (ok);
  94. }
  95.  
  96. /*
  97.  *-------------------------------------
  98.  * define a new var from input file
  99.  *-------------------------------------
  100.  */
  101.  
  102. /*
  103.  * read_enum_str
  104.  *
  105.  * sidefx: modifies tmpstr
  106.  */
  107. static BOOL read_enum_str(HSCPRC * hp, HSCATTR * var)
  108. {
  109.     HSCATTR *attr = new_hscattr(PREFIX_TMPATTR "enumerator");
  110.     attr->vartype = VT_STRING;
  111.  
  112.     /* store enumstr in var-struct */
  113.     if (eval_expression(hp, attr, NULL))
  114.     {
  115.         DDA(fprintf(stderr, DHL "  enum: %s\n", estr2str(hp->tmpstr)));
  116.         var->enumstr = strclone(get_vartext(attr));
  117.     }
  118.  
  119.     del_hscattr(attr);
  120.  
  121.     return ((BOOL) (!hp->fatal));
  122. }
  123.  
  124. /*
  125.  * check_attr_option
  126.  *
  127.  * check if a attribute-option-string is equal to an id/short id.
  128.  * if so, set the corresponding option value within the attribute.
  129.  *
  130.  * params: option..option string to check for (read from input)
  131.  *         attr....attribute to update option value for
  132.  *         id......id string of option (eg "REQUIRED")
  133.  *         sid.....short id string (eg "R")
  134.  *         value...option value to OR with old tag's option value
  135.  * result: TRUE, if tag's option value updated
  136.  */
  137. static BOOL check_attr_option(HSCPRC * hp, STRPTR option, HSCATTR * attr, STRPTR id, STRPTR sid, ULONG value, ULONG unmasked_flags)
  138. {
  139.     BOOL found = FALSE;
  140.  
  141.     if (!((upstrcmp(option, id)) && (upstrcmp(option, sid))))
  142.     {
  143.         DDA(fprintf(stderr, DHL "  option %s\n", id));
  144.  
  145.         if (value & unmasked_flags)
  146.         {
  147.             hsc_message(hp, MSG_ILLG_ATTR_FLAG,
  148.                         "attribute option %q not allowed in this context",
  149.                         id);
  150.         }
  151.         else
  152.             attr->varflag |= value;
  153.  
  154.         found = TRUE;
  155.     }
  156.  
  157.     return (found);
  158. }
  159.  
  160. /*
  161.  * define_var
  162.  *
  163.  * define a new var with reading its def from input file
  164.  * (starts parsing after ":", so ":" has to be read before)
  165.  *
  166.  * params: varname..name of new var
  167.  *         varlist..list new var should be inserted at the beginning
  168.  *         inpf.....input file where to read def from
  169.  *         flag.....flags: VF_ONLYONCE to avoid re-definition of a var
  170.  * result: ptr to new var
  171.  *
  172.  * definition syntax in input file:
  173.  *   <vartype>[/flag]["="<deftext value>]
  174.  *   legal vartypes: see VT_STR_xx in "vars.h"
  175.  *   legal flags   : see VF_STR_xx in "vars.h"
  176.  */
  177. HSCATTR *define_var(HSCPRC * hp, DLLIST * varlist, ULONG unmasked_flags)
  178. {
  179.     HSCATTR *var = NULL;        /* result */
  180.     BOOL ok = FALSE;
  181.     BYTE val_vartype = VT_NONE; /* var-type (numeric) */
  182.     BOOL newattr = FALSE;       /* next word read from input */
  183.     STRPTR nw = NULL;
  184.     STRPTR varname = NULL;
  185.     BOOL eof_called = FALSE;    /* used at end-of-func, if nw==NULL */
  186.     INFILE *inpf = hp->inpf;
  187.  
  188.     /* read attribute name */
  189.     nw = infget_attrid(hp);
  190.     if (nw)
  191.     {
  192.         varname = strclone(nw); /* remember attribute name */
  193.     }
  194.     else
  195.         eof_called = TRUE;      /* err_eof() called already */
  196.  
  197.     /* read attribute type */
  198.     if (nw)
  199.         if (parse_wd(hp, ":"))
  200.         {
  201.             nw = infgetw(inpf);
  202.             if (nw)
  203.                 val_vartype = str2vartype(nw);
  204.         }
  205.         else
  206.             inungetcw(inpf);
  207.  
  208.     if (nw)
  209.     {
  210.         /*
  211.          * look if attr already exist;
  212.          * if yes, clear old attribute
  213.          * to redefine the new one
  214.          */
  215.         var = find_varname(varlist, varname);
  216.         if (var)
  217.         {
  218.             DLNODE *nd = find_attrnode(varlist, varname);
  219.  
  220.             /* remove old attribute */
  221.             if (nd)
  222.                 del_dlnode(varlist, nd);
  223.             else
  224.                 panic("no node for redefined attribute");
  225.  
  226.             hsc_message(hp, MSG_ATTR_REDEFINED,
  227.                         "redefined %a", varname);
  228.         }
  229.  
  230.         /*
  231.          * create new attribute
  232.          */
  233.         DDA(fprintf(stderr, DHL "new attr: %s\n", varname));
  234.         var = app_var(varlist, varname);
  235.  
  236.         /* set type */
  237.         var->vartype = val_vartype;
  238.         if (var->vartype == VT_ENUM)
  239.         {
  240.             /* init enum-attribute */
  241.             read_enum_str(hp, var);
  242.         }
  243.         else if (var->vartype == VT_BOOL)
  244.         {
  245.             /* init boolean attr with FALSE */
  246.             set_varbool(var, FALSE);
  247.         }
  248.  
  249.         newattr = TRUE;
  250.  
  251.     }
  252.  
  253.     /* disable "/STRIPEXT" and "/GETSIZE" for non-URI-attributes */
  254.     if (nw)
  255.     {
  256.         if (var->vartype != VT_URI)
  257.             unmasked_flags |= VF_GETSIZE | VF_STRIPEXT;
  258.  
  259.         nw = infgetw(inpf);     /* get net word */
  260.     }
  261.  
  262.     /*
  263.      * handle attribute flags
  264.      */
  265.     while (nw && !strcmp(nw, "/"))
  266.     {
  267.         nw = infgetw(inpf);     /* read flag identifier */
  268.         if (nw)
  269.         {
  270.             BOOL ok = FALSE;
  271.  
  272.             ok |= check_attr_option(hp, nw, var,
  273.                                     VF_CONST_STR, VF_CONST_SHT,
  274.                                     VF_CONST, unmasked_flags);
  275.             ok |= check_attr_option(hp, nw, var,
  276.                                     VF_GLOBAL_STR, VF_GLOBAL_SHT,
  277.                                     VF_GLOBAL, unmasked_flags);
  278.             ok |= check_attr_option(hp, nw, var,
  279.                                     VF_JERK_STR, VF_JERK_SHT,
  280.                                     VF_JERK, unmasked_flags);
  281.             ok |= check_attr_option(hp, nw, var,
  282.                                     VF_ONLYONCE_STR, VF_ONLYONCE_SHT,
  283.                                     VF_ONLYONCE, unmasked_flags);
  284.             ok |= check_attr_option(hp, nw, var,
  285.                                     VF_REQUIRED_STR, VF_REQUIRED_SHT,
  286.                                     VF_REQUIRED, unmasked_flags);
  287.             ok |= check_attr_option(hp, nw, var,
  288.                                     VF_GETSIZE_STR, VF_GETSIZE_SHT,
  289.                                     VF_GETSIZE, unmasked_flags);
  290.             ok |= check_attr_option(hp, nw, var,
  291.                                     VF_STRIPEXT_STR, VF_STRIPEXT_SHT,
  292.                                     VF_STRIPEXT, unmasked_flags);
  293.             if (!ok)
  294.             {
  295.                 hsc_message(hp, MSG_UNKN_ATTR_OPTION,
  296.                             "unknown attribute flag %q", nw);
  297.             }
  298.  
  299.             /* read next word (should be "/", "=" or next attr / ">") */
  300.             nw = infgetw(inpf);
  301.         }
  302.         else
  303.             hsc_msg_eof(hp, "defining attribute");
  304.  
  305.     }
  306.  
  307.     /*
  308.      * handle default value
  309.      */
  310.     if (nw && !strcmp(nw, "="))
  311.     {
  312.         /* get new deftext value */
  313.         STRPTR new_deftext = NULL;
  314.         LONG old_attrflag = var->varflag;
  315.  
  316.         /* disable quotemode-checking */
  317.         var->varflag |= VF_KEEP_QUOTES;
  318.  
  319.         if (!(var->deftext))
  320.             new_deftext = eval_expression(hp, var, NULL);
  321.         else
  322.         {
  323.             STRPTR dummy;
  324.  
  325.             hsc_message(hp, MSG_SYMB_2ND_DEFAULT,
  326.                         "default value for %A already set", var);
  327.  
  328.             /* skip illegal default value */
  329.             dummy = eval_expression(hp, var, NULL);
  330.         }
  331.  
  332.         /* restore quotemode-checking */
  333.         var->varflag = old_attrflag;
  334.  
  335.         /* store default text value */
  336.         if (new_deftext)
  337.             var->deftext = strclone(new_deftext);
  338.  
  339.         /* read next word, only to be ungotten below */
  340.         nw = infgetw(inpf);
  341.     }
  342.  
  343.     /* check for unexpected end of file */
  344.     if (!nw)
  345.     {
  346.         if (!eof_called)
  347.             hsc_msg_eof(hp, "defining attribute");
  348.     }
  349.     else
  350.     {
  351.         /* end of var definition reached */
  352.         inungetcw(inpf);
  353.         ok = TRUE;
  354.     }
  355.  
  356.     /* cleanup */
  357.     if (!ok && var)
  358.     {
  359.         DLNODE *nd = find_attrnode(varlist,varname);
  360.         if (nd)
  361.             del_dlnode(varlist, (APTR) nd);
  362.         else
  363.             del_hscattr(var);
  364.         var = NULL;
  365.     }
  366.     ufreestr(varname);
  367.  
  368.     return (var);
  369. }
  370.  
  371. /*
  372.  *-------------------------------------
  373.  * copy & remove local vars to/from
  374.  * global varlist
  375.  *-------------------------------------
  376.  */
  377.  
  378. /*
  379.  * copy_local_var
  380.  *
  381.  * copies a local attribute to the global attribute list
  382.  *
  383.  * NOTE: the VF_MACRO-flag of the copy is disabled!
  384.  */
  385. static HSCATTR *copy_local_var(DLLIST * destlist, HSCATTR * locvar, ULONG mci)
  386. {
  387.     HSCATTR *var = app_var(destlist, locvar->name);
  388.  
  389.     var->macro_id = mci;
  390.     var->vartype = locvar->vartype;
  391.     var->varflag = locvar->varflag & (~VF_MACRO);       /* disable VF_MACRO */
  392.     set_vartext(var, locvar->text);
  393.     var->quote = locvar->quote;
  394.  
  395.     return (var);
  396. }
  397.  
  398. /*
  399.  * copy_local_vars
  400.  *
  401.  * add all local attributes of a macro to the global
  402.  * attribute list.
  403.  *
  404.  */
  405. BOOL copy_local_varlist(DLLIST * destlist, DLLIST * varlist, ULONG mci)
  406. {
  407.     BOOL ok = TRUE;
  408.  
  409.     if (mci == MCI_ERROR)
  410.         panic("mci=MCI_ERROR");
  411.     else
  412.     {
  413.         DLNODE *nd = varlist->first;
  414.         HSCATTR *var;
  415.  
  416.         while (nd && ok)
  417.         {
  418.             var = copy_local_var(destlist, (HSCATTR *) (nd->data), mci);
  419.             ok &= (BOOL) (var != NULL);
  420.             nd = nd->next;
  421.         }
  422.     }
  423.  
  424.     return (ok);
  425. }
  426.  
  427. /*
  428.  * set_local_var
  429.  *
  430.  * copies a local attribute to the global attribute list
  431.  *
  432.  * NOTE: the VF_MACRO-flag of the set is enabled!
  433.  */
  434. static HSCATTR *set_local_var(DLLIST * destlist, HSCATTR * locvar, ULONG mci)
  435. {
  436.     HSCATTR *var = find_varname(destlist, locvar->name);
  437.  
  438.     if (var)
  439.     {
  440.         var->macro_id = mci;
  441.         var->vartype = locvar->vartype;
  442.         set_vartext(var, locvar->text);
  443.     }
  444.     else
  445.         panic("set_local_var to UNKNOWN ATTR");
  446.  
  447.     return (var);
  448. }
  449.  
  450. /*
  451.  * set_local_vars
  452.  *
  453.  * add all local attributes of a macro to the global
  454.  * attribute list.
  455.  *
  456.  */
  457. BOOL set_local_varlist(DLLIST * destlist, DLLIST * varlist, ULONG mci)
  458. {
  459.     BOOL ok = TRUE;
  460.  
  461.     if (mci == MCI_ERROR)
  462.         panic("mci=MCI_ERROR");
  463.     else
  464.     {
  465.         DLNODE *nd = varlist->first;
  466.         HSCATTR *var;
  467.  
  468.         while (nd && ok)
  469.         {
  470.             var = set_local_var(destlist, (HSCATTR *) (nd->data), mci);
  471.             ok &= (BOOL) (var != NULL);
  472.             nd = nd->next;
  473.         }
  474.     }
  475.  
  476.     return (ok);
  477. }
  478.  
  479. /*
  480.  * remove_local_varlist
  481.  */
  482. VOID remove_local_varlist(DLLIST * varlist, ULONG mci)
  483. {
  484.     DLNODE *nd = varlist->first;
  485.  
  486.     while (nd)
  487.     {
  488.         HSCATTR *var = (HSCATTR *) nd->data;    /* var data of node */
  489.         DLNODE *nd_nxt = nd->next;      /* next node */
  490.  
  491.         if (var->macro_id == mci)
  492.             del_dlnode(varlist, nd);
  493.  
  494.         nd = nd_nxt;
  495.     }
  496. }
  497.  
  498.